package handler

import (
	"context"
	"encoding/json"
	"fmt"
	"user/dao/mysql"
	"user/model"
	"user/proto"
	"user/utils"
)

/*
user.go 和 user.pb.go 之间的交互主要通过 Protocol Buffers (protobuf) 的 RPC (Remote Procedure Call) 服务实现。在这个例子中，user.pb.go 是由 protobuf 编译器从 .proto 文件生成的，它定义了 RPC 服务接口和消息类型。

在 user.go 文件中，定义了一个 User 结构体，这个结构体实现了 user.pb.go 中定义的 RPC 服务接口。例如，SendSms, Register, Login, GetUserInfo, PutUserInfo 和 SaveRealName 方法都是 User 结构体实现的 RPC 服务接口。

这些方法的参数和返回值都是 user.pb.go 中定义的消息类型。例如，SendSms 方法的参数是 *user.Request，返回值是 *user.Response，这两个类型都是在 user.pb.go 中定义的。

当客户端调用这些 RPC 服务时，会通过网络将请求消息发送到服务器，服务器接收到请求后，会调用 user.go 中对应的方法处理请求，并将处理结果封装成响应消息返回给客户端。这就是 user.go 和 user.pb.go 之间的交互方式
*/

type User struct{}

// New Return a new handler
func New() *User {
	return &User{}
}

// SendSms Call is a single request handler called via client.Call or the generated client code

// func (e *User) SendSms(ctx context.Context, req *pb.Request, rsp *pb.Response) error {

func (e *User) SendSms(ctx context.Context, req *user.Request) (*user.Response, error) {
	// 校验图片验证码是否正确
	result := model.CheckImgCode(req.ImgUuid, req.ImgCode)
	if result {
		// 验证码通过 发送手机短信
		smdCode, err := utils.GetPhoneCode(req.Mobile)
		if err != nil {
			fmt.Println("生成手机验证码失败")
			return &user.Response{
				Errno:  utils.RECODE_SMSERR,
				Errmsg: utils.RecodeText(utils.RECODE_SMSERR),
			}, nil
		}
		fmt.Println("redis.SaveSmsCode(req.Mobile, code)", smdCode, err)

		//将短信验证码存入redis
		err = model.SaveSmsCode(req.Mobile, smdCode)
		if err != nil {
			fmt.Println("存储短信验证码redis失败: ", err)
			return &user.Response{
				Errno:  utils.RECODE_DBERR,
				Errmsg: utils.RecodeText(utils.RECODE_DBERR),
			}, nil
		}
	} else {
		fmt.Println("校验图片验证码错误")
	}

	fmt.Println("微服务（短信验证码）被调用成功。")

	// 短信验证码发送成功
	return &user.Response{
		Errno:  utils.RECODE_OK,
		Errmsg: utils.RecodeText(utils.RECODE_OK),
	}, nil

}

// Register 用户注册微服务
func (e *User) Register(ctx context.Context, req *user.RegReq) (*user.Response, error) {
	// 校验短信验证码是否正确 redis中存储了短信验证码
	fmt.Println("req:", req)
	res := model.CheckSmsCode(req.Mobile, req.SmsCode)
	if res == false {
		fmt.Println("手机验证码校验失败")
		return &user.Response{
			Errno:  utils.RECODE_DATAERR,
			Errmsg: utils.RecodeText(utils.RECODE_DATAERR),
		}, nil
	}

	// 验证用户是否已经注册
	existRes := mysql.CheckUserExist(req.Mobile)
	if existRes == true {
		// 用户存在 注册失败
		fmt.Println("用户存在注册失败")
		return &user.Response{
			Errno:  utils.RECODE_USERONERR,
			Errmsg: utils.RecodeText(utils.RECODE_USERONERR),
		}, nil
	}

	// 校验通过 注册用户 写入mysql
	err := mysql.RegisterUser(req.Mobile, req.Password)
	if err != nil {
		fmt.Println("用户存储数据库失败")
		return &user.Response{
			Errno:  utils.RECODE_DBERR,
			Errmsg: utils.RecodeText(utils.RECODE_DBERR),
		}, nil
	}

	fmt.Println("用户注册成功")
	return &user.Response{
		Errno:  utils.RECODE_OK,
		Errmsg: utils.RecodeText(utils.RECODE_OK),
	}, nil
}

func (e *User) Login(ctx context.Context, req *user.RegReq) (*user.Response, error) {

	res, _ := mysql.CheckUserNameAndPWD(req.Mobile, req.Password)
	if res == false {
		fmt.Println("用户名或密码错误")
		return &user.Response{
			Errno:  utils.RECODE_LOGINERR,
			Errmsg: utils.RecodeText(utils.RECODE_LOGINERR),
		}, nil
	}

	fmt.Println("用户登陆服务验证成功！！！！！！！！")

	//else {
	//
	//	// 将登陆状态，保存到Session中, Session需要保存在用户本地，而不是一服务端
	//	session := sessions.Default(ctx) // 调用session, 设置session数据
	//	nowName, _ := mysql.GetUserName(req.Mobile)
	//	println("从mysql登陆名： ", nowName)
	//	session.Set("userName", nowName)
	//	session.Save()
	//}

	return &user.Response{
		Errno:  utils.RECODE_OK,
		Errmsg: utils.RecodeText(utils.RECODE_OK),
	}, nil
}

// GetUserInfo 获取用户信息微服务
func (e *User) GetUserInfo(ctx context.Context, req *user.GetUserInfoReq) (*user.GetUserInfoResp, error) {
	// 读取数据库的用户信息
	userInfo, err := mysql.GetUserInfo(req.Name)
	if err != nil {
		fmt.Println("用户查询失败")
		return &user.GetUserInfoResp{
			Errno:  utils.RECODE_USERERR,
			Errmsg: utils.RecodeText(utils.RECODE_USERERR),
			User:   "",
		}, nil
	}
	bytes, err := json.Marshal(&userInfo)
	if err != nil {
		fmt.Println("用户序列化失败")
		return &user.GetUserInfoResp{
			Errno:  utils.RECODE_DATAERR,
			Errmsg: utils.RecodeText(utils.RECODE_DATAERR),
			User:   "",
		}, nil
	}
	return &user.GetUserInfoResp{
		Errno:  utils.RECODE_OK,
		Errmsg: utils.RecodeText(utils.RECODE_OK),
		User:   string(bytes),
	}, nil
}

// PutUserInfo 修改用户名
func (e *User) PutUserInfo(ctx context.Context, req *user.PutUserInfoReq) (*user.Response, error) {
	// 数据库更新用户名
	err := mysql.UpdateUserName(req.OName, req.Name)
	if err != nil {
		fmt.Println("用户名更新失败")
		return &user.Response{
			Errno:  utils.RECODE_DBERR,
			Errmsg: utils.RecodeText(utils.RECODE_DBERR),
		}, nil
	}

	return &user.Response{
		Errno:  utils.RECODE_OK,
		Errmsg: utils.RecodeText(utils.RECODE_OK),
	}, nil
}

func (e *User) SaveRealName(ctx context.Context, req *user.SaveRealNameReq) (*user.Response, error) {
	err := mysql.SaveRealName(req.Name, req.RealName, req.IdCard)
	if err != nil {
		fmt.Println("保存用户实名信息错误err:", err)
		return &user.Response{
			Errno:  utils.RECODE_DBERR,
			Errmsg: utils.RecodeText(utils.RECODE_DBERR),
		}, nil
	}
	return &user.Response{
		Errno:  utils.RECODE_OK,
		Errmsg: utils.RecodeText(utils.RECODE_OK),
	}, nil
}
